/*!
事件模块，绑定sciter js端发起的事件交互
*/
extern crate sciter;

use crate::redis_helper;
use crate::redis_helper::Connector;
use crate::sqlite;
use sciter::{Element, EventHandler, Value};
use std::collections::HashMap;
use std::option::Option::Some;
use std::result::Result::Ok;

/// 定义公共事件
pub trait Event {
    /// 分发全局事件
    fn global_event(&mut self, evt_name: String, data: Value) -> Value {
        if let Ok(root) = Element::create("div") {
            if let Ok(_) = root.broadcast_event(&evt_name, true, Some(data)) {
                Value::from(true)
            } else {
                Value::from(false)
            }
        } else {
            Value::from(false)
        }
    }
    /// 创建主窗口
    fn create_main_window(&mut self) {
        super::windows::create_main(*super::RESOURCE);
    }
    /// 退出方法
    fn exit(&mut self) {
        std::process::exit(0);
    }
    fn current_path(&mut self) -> Value {
        let val = std::env::current_dir()
            .unwrap()
            .as_path()
            .display()
            .to_string();
        Value::from(val)
    }
}

/// 事件列表
pub struct Events {}

/// 方法
impl Events {
    /// 初始话sqlite
    pub fn init_sqlite(&mut self, path: String) -> Value {
        sqlite::DB_PATH.lock().unwrap().set(path);
        match sqlite::init() {
            Ok(_) => vmap! {
                "status" => 1,
            "msg" => "success"
            },
            Err(e) => vmap! {
                "status" => 0,
                "msg" => e.to_string()
            },
        }
    }
    /// 解析参数
    fn parse_params(&mut self, data: Value) -> std::collections::HashMap<String, String> {
        let id = data
            .get_item("id")
            .as_string()
            .unwrap_or(uuid::Uuid::new_v4().to_string());
        let name = data.get_item("name").as_string().unwrap_or(String::new());
        let address = data
            .get_item("address")
            .as_string()
            .unwrap_or(String::new());
        let port = data.get_item("port").as_string().unwrap_or(String::new());
        let password = data
            .get_item("password")
            .as_string()
            .unwrap_or(String::new());
        let db = data.get_item("db").as_string().unwrap_or(String::from("0"));
        let mut map = HashMap::new();
        map.insert("id".into(), id);
        map.insert("name".into(), name);
        map.insert("address".into(), address);
        map.insert("port".into(), port);
        map.insert("password".into(), password);
        map.insert("db".into(), db);
        map
    }
    /// sqlite添加一个连接
    pub fn add_conn(&mut self, data: Value) -> Value {
        let map = self.parse_params(data);
        let _id = &map["id"];
        let _name = &map["name"];
        let _address = &map["address"];
        let _port = &map["port"];
        let _password = &map["password"];
        if _name == "" || _address == "" || _port == "" {
            return Value::from(false);
        }
        match sqlite::connect() {
            Ok(conn) => {
                if let Ok(res) = conn.execute(
                    "replace into connect(id,name,address,port,password) values(?1,?2,?3,?4,?5)",
                    rusqlite::params![_id, _name, _address, _port, _password],
                ) {
                    Value::from(res > 0)
                } else {
                    Value::from(false)
                }
            }
            _ => Value::from(false),
        }
    }
    /// sqlite查询连接
    pub fn query_conn(&mut self, _id: String) -> Value {
        if let Ok(res) = sqlite::query_conn_list() {
            let serialize = serde_json::to_string(&res).unwrap_or("[]".to_string());
            Value::parse(&serialize).unwrap_or(varray![])
        } else {
            varray![]
        }
    }
    /// sqlite删除连接
    pub fn delete_conn(&mut self, _id: String) -> Value {
        match sqlite::connect() {
            Ok(conn) => {
                if let Ok(res) =
                    conn.execute("delete from connect where id = ?1", rusqlite::params![_id])
                {
                    Value::from(res > 0)
                } else {
                    Value::from(false)
                }
            }
            Err(_e) => Value::from(false),
        }
    }
    /// 连接到redis
    pub fn connect_redis(&mut self, data: Value) -> Value {
        let map = self.parse_params(data);
        let _id = &map["id"];
        let _name = &map["name"];
        let _address = &map["address"];
        let _port = &map["port"];
        let _password = &map["password"];
        let _db = &map["db"];
        match redis_helper::REDIS.lock() {
            Ok(mut cfg) => {
                cfg.set(_address, _port, _db, _password, "");
                if let Some(_) = cfg.connect() {
                    Value::from(true)
                } else {
                    Value::from(false)
                }
            }
            _ => Value::from(false),
        }
    }
    /// 异步连接模式
    pub fn async_connect_redis(&mut self, data: Value, cb: Value) -> bool {
        std::thread::spawn(move || {
            let address = data
                .get_item("address")
                .as_string()
                .unwrap_or(String::new());
            let port = data.get_item("port").as_string().unwrap_or(String::new());
            let password = data
                .get_item("password")
                .as_string()
                .unwrap_or(String::new());
            let db = data.get_item("db").as_string().unwrap_or(String::from("0"));
            let username = data
                .get_item("username")
                .as_string()
                .unwrap_or(String::from(""));
            let res = redis_helper::connect_redis(address, port, db, password, username);
            cb.call(None, &make_args!(res), None)
                .unwrap_or(Value::null());
        });
        true
    }
    /// 获取redis信息
    pub fn get_redis_info(&mut self) -> Value {
        match redis_helper::REDIS.lock() {
            Ok(mut cfg) => {
                if let Some(mut conn) = cfg.connect() {
                    return if let Ok(res) = redis::cmd("info").query::<String>(&mut conn) {
                        Value::from(res)
                    } else {
                        Value::from("")
                    };
                };
                Value::from("")
            }
            _ => Value::from(""),
        }
    }
    /// 获取redis数据库个数
    pub fn get_redis_dbs(&mut self) -> Value {
        let res = redis_helper::get_db();
        Value::from(&res["databases"])
    }
    /// 获取keys
    pub fn get_keys(&mut self, condition: String) -> Value {
        let res = redis_helper::get_keys(&condition);
        let serialize = serde_json::to_string(&res).unwrap();
        Value::parse(&serialize).unwrap_or(Value::from("[]"))
    }
    /// 获取基本信息
    pub fn get_infos(&mut self, key: String) -> Value {
        Value::from(redis_helper::get_infos(key))
    }
    /// 获取string类型的key值
    pub fn get_string_val(&mut self, key: String) -> Value {
        match redis_helper::get_string_val(key) {
            Some(val) => Value::from(val),
            None => Value::null(),
        }
    }
    /// 删除key值
    pub fn delete_key(&mut self, key: String) -> Value {
        let val = redis_helper::delete_key(key);
        Value::from(val)
    }
    /// key是否存在
    pub fn is_key_exist(&mut self, key: String) -> Value {
        let val = redis_helper::key_exist(key);
        Value::from(val)
    }
    /// 添加string key
    pub fn add_string_key(
        &mut self,
        key: String,
        value: String,
        time: String,
        time_type: String,
    ) -> Value {
        let val = redis_helper::add_string_key(key, value, time, time_type);
        Value::from(val)
    }
    /// 重命名key
    pub fn rename_key(&mut self, o_key: String, n_key: String) -> Value {
        let val = redis_helper::rename_key(o_key, n_key);
        Value::from(val)
    }
    /// 设置过期时间
    pub fn set_expire(&mut self, key: String, t: String, time: String) -> Value {
        let _val = redis_helper::set_key_expire(key, t, time);
        Value::from(_val)
    }
    /// 获取list数据
    pub fn get_list_val(&mut self, key: String, page: i32, range: i32) -> Value {
        let res = redis_helper::get_list_val(key, page as usize, range as usize);
        match res {
            Ok(result) => {
                let res = serde_json::to_string(&result).unwrap_or("[]".to_string());
                Value::from(res)
            }
            Err(err) => {
                println!("at events.rs line 238 : \nerr {}", err);
                Value::from("{}")
            }
        }
    }
    /// 修改list类型的值
    pub fn set_list_index_val(&mut self, key: String, index: i32, value: String) -> Value {
        let res = redis_helper::set_list_index_val(key, index, value);
        Value::from(res)
    }
    /// 修改list类型的值
    pub fn delete_list_index_val(&mut self, key: String, value: String) -> Value {
        let res = redis_helper::delete_list_index_val(key, value);
        Value::from(res)
    }
    /// 将一个值插入到已存在的列表
    pub fn append_list_val(&mut self, key: String, t: String, value: String) -> Value {
        let res = redis_helper::append_list_val(key, t, value);
        Value::from(res)
    }
    /// 裁剪一个list
    pub fn clip_list(&mut self, key: String, start: i32, end: i32) -> Value {
        let res = redis_helper::clip_list(key, start, end);
        Value::from(res)
    }
    /// 获取hash数据
    pub fn get_hash_data(&mut self, key: String) -> Value {
        let res = redis_helper::get_hash_data(key);
        let res = serde_json::to_string(&res).unwrap_or(format!("[]"));
        Value::parse(&res).unwrap_or(varray![])
    }
    /// 修改hash数据
    pub fn edit_hash_data(&mut self, key: String, field: String, value: String) -> Value {
        let res = redis_helper::edit_hash_data(key, field, value);
        Value::from(res)
    }
    /// 修改hash数据
    pub fn append_hash_data(&mut self, key: String, field: String, value: String) -> Value {
        let res = redis_helper::append_hash_data(key, field, value);
        Value::from(res)
    }

    /// 获取set数据
    pub fn get_set_data(&mut self, key: String) -> Value {
        let res = redis_helper::get_set_data(key);
        let ser = serde_json::to_string(&res).unwrap_or(format!("[]"));
        Value::parse(&ser).unwrap_or(varray![])
    }
    /// 添加一个set数据
    pub fn append_set_val(&mut self, key: String, value: String) -> Value {
        let res = redis_helper::append_set_val(key, value);
        Value::from(res)
    }
    /// 删除一个set数据
    pub fn delete_set_val(&mut self, key: String, value: String) -> Value {
        let res = redis_helper::delete_set_val(key, value);
        Value::from(res)
    }
    /// 添加list key
    pub fn add_list_key(&mut self, key: String, value: String) -> Value {
        let res = redis_helper::add_list_key(key, value);
        Value::from(res)
    }
    /// async lst
    pub fn async_get_set_data(&mut self, key: String, cb: Value) -> bool {
        std::thread::spawn(move || {
            let res = redis_helper::get_set_data(key);
            let ser = serde_json::to_string(&res).unwrap_or(format!("[]"));
            let res = Value::parse(&ser).unwrap_or(varray![]);
            cb.call(None, &make_args!(res), None)
                .unwrap_or(Value::null());
        });

        true
    }
}

/// 实现trait
impl Event for Events {}

/// 绑定sciter交互
impl EventHandler for Events {
    sciter::dispatch_script_call! {
        fn global_event(String,Value);
        fn current_path();
        fn init_sqlite(String);
        fn add_conn(Value);
        fn create_main_window();
        fn query_conn(String);
        fn delete_conn(String);
        fn connect_redis(Value);
        fn async_connect_redis(String,Value);
        fn get_redis_info();
        fn get_redis_dbs();
        fn get_keys(String);
        fn get_infos(String);
        fn get_string_val(String);
        fn delete_key(String);
        fn is_key_exist(String);
        fn add_string_key(String,String,String,String);
        fn rename_key(String,String);
        fn set_expire(String,String,String);
        fn get_list_val(String,i32,i32);
        fn set_list_index_val(String,i32,String);
        fn delete_list_index_val(String,String);
        fn append_list_val(String,String,String);
        fn clip_list(String,i32,i32);
        fn get_hash_data(String);
        fn edit_hash_data(String,String,String);
        fn append_hash_data(String,String,String);
        fn get_set_data(String);
        fn async_get_set_data(String,Value);
        fn append_set_val(String,String);
        fn delete_set_val(String,String);
        fn add_list_key(String,String);
        fn exit();
    }
}
